<template>
  <div class="v-simple-cropper">
    <div v-if="$slots.default" @click="upload">
      <slot v-bind="{ img }" />
    </div>
    <input
      ref="file"
      class="file"
      name="file"
      type="file"
      accept="image/*"
      @change="uploadChange"
    >
    <div ref="layer" class="v-cropper-layer">
      <div class="imgeditwrap">
        <div class="iner-wrap">
          <div class="layer-header" :style="{ backgroundColor: themebg }">
            <el-button size="small" @click="cancelHandle">取消</el-button>
            <el-button
              size="small"
              :disabled="uploading"
              type="primary"
              @click="confirmHandle"
            >确定</el-button>
          </div>
          <img ref="cropperImg">
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.min.css'

export default {
  name: 'SimpleCropper',
  props: {
    initParam: {
      type: Object,
      default: () => {
        return {
          scale: 2 // 相对手机屏幕放大的倍数: 4倍
        }
      }
    },
    img: {
      type: String,
      default: ''
    },
    successCallback: {
      type: Function,
      required: false,
      default: () => {}
    },
    themebg: {
      type: String,
      default: 'rgb(0,0,0,0)'
    },
    // 裁剪比例
    ratio: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      cropper: {},
      uploading: false, // 是否在上传中
      filename: ''
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化裁剪插件
    init() {
      const cropperImg = this.$refs.cropperImg
      const self = this
      this.cropper = new Cropper(cropperImg, {
        aspectRatio: this.ratio,
        dragMode: 'move',
        background: false,
        movable: false,
        // viewMode: 1,
        ready() {
          // 动态设置遮罩背景
          const ele = self.$refs.layer.querySelector('.cropper-container')
          ele.style.background = self.themebg
        }
      })
    },
    // 点击上传按钮,触发选择图片
    upload() {
      this.$refs.file.click()
    },
    // 选择上传文件
    uploadChange(e) {
      const file = e.target.files[0]
      this.filename = file.name
      const URL = window.URL || window.webkitURL
      this.$refs.layer.style.display = 'block'
      this.cropper.replace(URL.createObjectURL(file))
    },
    // 取消上传
    cancelHandle() {
      this.uploading = false
      this.cropper.reset()
      this.$refs.layer.style.display = 'none'
      this.$refs.file.value = ''
      this.cropper.destroy()
    },
    // 确定上传
    async confirmHandle() {
      this.uploading = true
      const cropBox = this.cropper.getCropBoxData()
      const scale = this.initParam.scale || 1
      const cropCanvas = this.cropper.getCroppedCanvas({
        width: cropBox.width * scale,
        height: cropBox.height * scale,
        fillColor: this.themebg
      })
      // const base64 = cropCanvas.toDataURL('image/jpeg')
      // const blob = this.dataURLtoBlob(base64)
      cropCanvas.toBlob(async blob => {
        const formData = new FormData()
        let filename = this.$refs.file.files[0].name
        formData.append('file', blob)
        // 处理中文文件名
        if (/.*[\u4e00-\u9fa5]+.*$/.test(filename)) {
          const tem = filename.split('.')
          filename = new Date().getTime() + '.' + tem[tem.length - 1]
        }
        const results = await this.$http.cutUpload({
          fileName: filename,
          formData
        })
        // eslint-disable-next-line eqeqeq
        if (results.code == 200) {
          this.$emit('update:img', results.file)
          if (this.successCallback instanceof Function) {
            this.successCallback(results.file)
          }
          this.cancelHandle()
        }
      })
    }
    // base64 转化为 blob
    // dataURLtoBlob(dataurl) {
    //   const arr = dataurl.split(',')
    //   const mime = arr[0].match(/:(.*?);/)[1]
    //   const bstr = atob(arr[1])
    //   let n = bstr.length
    //   const u8arr = new Uint8Array(n)
    //   while (n--) {
    //     u8arr[n] = bstr.charCodeAt(n)
    //   }
    //   return new Blob([u8arr], { type: mime })
    // },
    // 压缩图片
    /*  compressImage: function(bdata) {
      var _this = this
      var quality = 0.3 // 压缩图片的质量
      var oldimglength = bdata.length // 压缩前的大小
      var compresRadio = 0 // 压缩率

      var canvas = document.createElement('canvas') // 创建画布
      var ctx = canvas.getContext('2d')

      var img = new Image()
      img.src = bdata
      img.onload = function() {
        var width = img.width
        var height = img.height
        canvas.width = 100 // 这里可以自定义你的图片大小
        canvas.height = 100 * (img.height / img.width)
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
        var cdata = canvas.toDataURL('image/jpeg', quality) // 将图片转为Base64 之后预览要用

        // _this.HeadUrl = cdata; //预览你压缩后的图片
        var newimglength = cdata.length
        console.log(newimglength)
        console.log('img-blob:' + oldimglength) // 压缩前大小
        console.log('ctx-blob:' + newimglength) // 压缩后大小
        compresRadio =
          (((oldimglength - newimglength) / oldimglength) * 100).toFixed(2) +
          '%'
        console.log('压缩率:' + compresRadio)
        // base64转成file
        const arr = cdata.split(',')
        const mime = arr[0].match(/:(.*?);/)[1]
        const bstr = atob(arr[1])
        let n = bstr.length
        const u8arr = new Uint8Array(n)
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        const newFile = new File([u8arr], _this.filename, { type: mime })
        //  console.log(this.picValue)
        _this.url = _this.getObjectURL(newFile)
        // 每次替换图片要重新得到新的url
        if (_this.cropper) {
          _this.cropper.replace(this.url)
        }
        _this.panel = true
      }
    } */
  }
}
</script>

<style lang="scss">
.v-simple-cropper {
  .imgeditwrap {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 100;

    .iner-wrap {
      position: relative;
      min-height: 50vh;
      max-height: 80vh;
      margin: 0 auto;
      max-width: 80vw;
    }
  }

  .file {
    display: none;
  }

  ::v-deep .cropper-modal {
    opacity: inherit;
    background: none;
  }

  .v-cropper-layer {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 99999;
    display: none;

    .layer-header {
      position: absolute;
      width: 100%;
      transform: translateY(100%);
      bottom: 0;
      z-index: 99999;
      box-sizing: border-box;
      padding: 10px;
      display: flex;
      justify-content: space-between;

      .van-button {
        padding: 2px 10px;
      }
    }

    .cancel,
    .confirm {
      line-height: 0.8rem;
      font-size: 0.28rem;
      background: inherit;
      border: 0;
      outline: 0;
      float: left;
    }

    .confirm {
      float: right;
    }

    img {
      position: inherit !important;
      border-radius: inherit !important;
      float: inherit !important;
    }
  }
}
</style>
